
`include "common_header.verilog"

//  *************************************************************************
//   File : pcs_tx_state_mc.v
//  *************************************************************************
//   This program is controlled by a written license agreement.
//   Unauthorized Reproduction or Use is Expressly Prohibited. 
// 
//  Copyright (c) 2005 Morethanip GmbH
//  info@morethanip.com
//  *************************************************************************
//  Version: $Id: rx_lane_dskew.v,v 1.5 2007/09/20 22:09:38 mr Exp $ 
//  Author : Muhammad Anisur Rahman
//  *************************************************************************
//  Description:
// 
//  PCS lane deskew control 
// 
//  *************************************************************************

module rx_lane_dskew (

   reset_sd0_rx_clk,
   reset_sd1_rx_clk,
   reset_sd2_rx_clk,
   reset_sd3_rx_clk,
   rx_sync,
   sd0_rx_clk,
  `ifdef USE_CLK_ENA
   sd0_rx_clk_ena,
  `endif    
   dec_kchar0,
   dec_data0,
   sd1_rx_clk,
  `ifdef USE_CLK_ENA
   sd1_rx_clk_ena,
  `endif    
   dec_kchar1,
   dec_data1,
   sd2_rx_clk,
  `ifdef USE_CLK_ENA
   sd2_rx_clk_ena,
  `endif    
   dec_kchar2,
   dec_data2,
   sd3_rx_clk,
  `ifdef USE_CLK_ENA
   sd3_rx_clk_ena,
  `endif    
   dec_kchar3,
   dec_data3,
   kchar0,
   data0,
   kchar1,
   data1,
   kchar2,
   data2,
   kchar3,
   data3,
  `ifdef MTIPXGXS_BUFRESET
   buf_reset,
  `endif
   align_done);
   
input   reset_sd0_rx_clk;       //  Asynchronous Reset - sd0_rx_clk Domain
input   reset_sd1_rx_clk;       //  Asynchronous Reset - sd1_rx_clk Domain
input   reset_sd2_rx_clk;       //  Asynchronous Reset - sd2_rx_clk Domain
input   reset_sd3_rx_clk;       //  Asynchronous Reset - sd3_rx_clk Domain
input   [3:0] rx_sync;          //  Receive Synchronization Status
input   sd0_rx_clk;             //  SERDES Lane 0 Clock
input   [1:0] dec_kchar0;       //  Special Character Indication
input   [15:0] dec_data0;       //  Decoded Data      
input   sd1_rx_clk;             //  SERDES Lane 0 Clock
input   [1:0] dec_kchar1;       //  Special Character Indication
input   [15:0] dec_data1;       //  Decoded Data 
input   sd2_rx_clk;             //  SERDES Lane 0 Clock
input   [1:0] dec_kchar2;       //  Special Character Indication
input   [15:0] dec_data2;       //  Decoded Data 
input   sd3_rx_clk;             //  SERDES Lane 0 Clock
input   [1:0] dec_kchar3;       //  Special Character Indication
input   [15:0] dec_data3;       //  Decoded Data
output  [1:0] kchar0;           //  Special Character Indication
output  [15:0] data0;           //  Decoded Data      
output  [1:0] kchar1;           //  Special Character Indication
output  [15:0] data1;           //  Decoded Data 
output  [1:0] kchar2;           //  Special Character Indication
output  [15:0] data2;           //  Decoded Data 
output  [1:0] kchar3;           //  Special Character Indication
output  [15:0] data3;           //  Decoded Data
 
`ifdef MTIPXGXS_BUFRESET
   output [3:0] buf_reset;      //  Rset buffers when deskew error occured
`endif

output  align_done;             //  Alignment completed

`ifdef USE_CLK_ENA
   input sd0_rx_clk_ena;        // Enable sd0_rx_clk
   input sd1_rx_clk_ena;        // Enable sd1_rx_clk
   input sd2_rx_clk_ena;        // Enable sd2_rx_clk
   input sd3_rx_clk_ena;        // Enable sd3_rx_clk
`endif 

wire    [1:0] kchar0; 
wire    [15:0] data0; 
wire    [1:0] kchar1; 
wire    [15:0] data1; 
wire    [1:0] kchar2; 
wire    [15:0] data2; 
wire    [1:0] kchar3; 

wire    [15:0] data3; 
`ifdef MTIPXGXS_BUFRESET
wire [3:0] buf_reset;      //  Rset buffers when deskew error occured
`endif
wire    align_done; 
wire    [1:0] align_dec_kchar0; 
wire    [1:0] align_dec_kchar1; 
wire    [1:0] align_dec_kchar2; 
wire    [1:0] align_dec_kchar3; 
wire    [15:0] align_dec_data0; 
wire    [15:0] align_dec_data1; 
wire    [15:0] align_dec_data2; 
wire    [15:0] align_dec_data3; 

wire    sudi_col_a;             //  SYNC UNIT DATA indicate column |A|
wire    deskew_error;           //  Lane Deskew Error
wire    enable_deskew;          //  Enable Lane Deskew 
wire    align_done_int;         //  Lane Alignment Done
wire    [3:0] buffer_rst;       //  Alignbuffer sync reset

lane_dskew_stm U_STM (

          .reset(reset_sd0_rx_clk),
          .clk(sd0_rx_clk),
          `ifdef USE_CLK_ENA
           .clk_ena(sd0_rx_clk_ena),
          `endif
          .rx_sync(rx_sync),
          .sudi_col_a(sudi_col_a),
          .deskew_error(deskew_error),
          .enable_deskew(enable_deskew),
          .align_done(align_done_int));

assign align_done = align_done_int; 

lan_rearrange U_LN0 (

          .clk(sd0_rx_clk),
          `ifdef USE_CLK_ENA
           .clk_ena(sd0_rx_clk_ena),
          `endif
          .reset(reset_sd0_rx_clk),
          .rx_sync(rx_sync),
          .enable_deskew(enable_deskew),
          .buffer_rst(buffer_rst[0]),
          .dec_kchar(dec_kchar0),
          .dec_data(dec_data0),
          .kchar(align_dec_kchar0),
          .data(align_dec_data0));

lan_rearrange U_LN1 (

          .clk(sd1_rx_clk),
          `ifdef USE_CLK_ENA
           .clk_ena(sd1_rx_clk_ena),
          `endif
          .reset(reset_sd1_rx_clk),
          .rx_sync(rx_sync),
          .enable_deskew(enable_deskew),
          .buffer_rst(buffer_rst[1]),
          .dec_kchar(dec_kchar1),
          .dec_data(dec_data1),
          .kchar(align_dec_kchar1),
          .data(align_dec_data1));

lan_rearrange U_LN2 (

          .clk(sd2_rx_clk),
          `ifdef USE_CLK_ENA
           .clk_ena(sd2_rx_clk_ena),
          `endif
          .reset(reset_sd2_rx_clk),
          .rx_sync(rx_sync),
          .enable_deskew(enable_deskew),
          .buffer_rst(buffer_rst[2]),
          .dec_kchar(dec_kchar2),
          .dec_data(dec_data2),
          .kchar(align_dec_kchar2),
          .data(align_dec_data2));

lan_rearrange U_LN3 (

          .clk(sd3_rx_clk),
          `ifdef USE_CLK_ENA
           .clk_ena(sd3_rx_clk_ena),
          `endif          
          .reset(reset_sd3_rx_clk),
          .rx_sync(rx_sync),
          .enable_deskew(enable_deskew),
          .buffer_rst(buffer_rst[3]),
          .dec_kchar(dec_kchar3),
          .dec_data(dec_data3),
          .kchar(align_dec_kchar3),
          .data(align_dec_data3));

rx_deskew_buf U_DSKW (

          .reset_sd0_rx_clk(reset_sd0_rx_clk),
          .reset_sd1_rx_clk(reset_sd1_rx_clk),
          .reset_sd2_rx_clk(reset_sd2_rx_clk),
          .reset_sd3_rx_clk(reset_sd3_rx_clk),
          .enable_deskew(enable_deskew),
          .rx_sync(rx_sync),
          .deskew_error(deskew_error),
          .buffer_rst(buffer_rst),
          .align_done(align_done_int),
          .sudi_col_a(sudi_col_a),
          .sd0_rx_clk(sd0_rx_clk),
          `ifdef USE_CLK_ENA
           .sd0_rx_clk_ena(sd0_rx_clk_ena),
          `endif          
          .dec_kchar0(align_dec_kchar0),
          .dec_data0(align_dec_data0),
          .sd1_rx_clk(sd1_rx_clk),
          `ifdef USE_CLK_ENA
           .sd1_rx_clk_ena(sd1_rx_clk_ena),
          `endif
          .dec_kchar1(align_dec_kchar1),
          .dec_data1(align_dec_data1),
          .sd2_rx_clk(sd2_rx_clk),
          `ifdef USE_CLK_ENA
           .sd2_rx_clk_ena(sd2_rx_clk_ena),
          `endif
          .dec_kchar2(align_dec_kchar2),
          .dec_data2(align_dec_data2),
          .sd3_rx_clk(sd3_rx_clk),
          `ifdef USE_CLK_ENA
           .sd3_rx_clk_ena(sd3_rx_clk_ena),
          `endif
          .dec_kchar3(align_dec_kchar3),
          .dec_data3(align_dec_data3),
          .kchar0(kchar0),
          .data0(data0),
          .kchar1(kchar1),
          .data1(data1),
          .kchar2(kchar2),
          .data2(data2),
          .kchar3(kchar3),
          .data3(data3));

`ifdef MTIPXGXS_BUFRESET
   assign buf_reset = buffer_rst;
`endif


endmodule // module rx_lane_dskew